﻿using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;
using Moq;
using NUnit.Framework;
using TeamsPortal.DataAccess;
using TeamsPortal.ServiceClient;
using TeamsPortal.Tests.Fakes;
using TeamsPortal.Web.Controllers;
using TeamsPortal.Web.Extensions;

namespace TeamsPortal.Tests.Controllers
{
	[TestFixture]
	public class TopicsControllerTest
	{
        //todo: remove when mocking is finished
		public static Topic GetATopic(Forum forum)
		{
			List<Topic> topicList = new TopicsServiceClient(new MessagesServiceClient()).GetByForum(forum.Id, 0, 1, null);

			if (topicList.Count == 0)
			{
				Assert.Inconclusive("There is no topic in the db to perform this test.");
			}
			Topic topic = new TopicsServiceClient(new MessagesServiceClient()).Get(topicList[0].Id);
			return topic;
		}

        [Test]
        public void Topic_Add()
        {
            const string forumShortName = "ShortName";
            const int topicId = 23;
            var topic = new Topic(){Id=23};
            var mockTopicClient = new Mock<ITopicsServiceClient>();
            var mockForumClient = new Mock<IForumsServiceClient>();
            var forum = new Forum() { ShortName = forumShortName };
            mockForumClient
                .Setup(m => m.Get(forumShortName))
                .Returns(forum);
            var mockTopicSubscriptionClient = new Mock<ITopicsSubscriptionsServiceClient>();
            mockTopicSubscriptionClient.Setup(m => m.Add(topicId, It.IsAny<int>()));

            var controller = new TopicsController(mockTopicClient.Object, null, mockForumClient.Object, mockTopicSubscriptionClient.Object);
            var controllerContext = FakeControllerContext.Create(controller, "http://localhost", ForumsControllerTest.GetSessionWithTestUser());
            controller.ControllerContext = controllerContext;

            string ip = controllerContext.RequestContext.HttpContext.Request.UserHostAddress;
            mockTopicClient.Setup(m => m.Create(topic, ip));
            
            ActionResult result = controller.Add(forum.ShortName, topic, true, "admin@admin.com");
            Assert.IsInstanceOf<RedirectToRouteResult>(result);//controller should display the same page to correct error.

            mockTopicClient.VerifyAll();
            mockForumClient.VerifyAll();
            mockTopicSubscriptionClient.VerifyAll();
        }

		[Test]
		public void Topic_Delete()
		{
            var mockTopicClient = new Mock<ITopicsServiceClient>();
            var controller = new TopicsController(mockTopicClient.Object, null, null, null);
            var controllerContext = FakeControllerContext.Create(controller, "http://localhost", ForumsControllerTest.GetSessionWithTestUser());
            controller.ControllerContext = controllerContext;
            controller.Url = new UrlHelper(controllerContext.RequestContext);

			//Create a valid topic
            string topicTitle = "Unit testing " + MethodInfo.GetCurrentMethod().Name;
            var topic = new Topic()
            {
                Title = topicTitle,
                Description = "This is a sample topic from unit testing project.",
                Tags = new TagList("test"),
                ShortName = topicTitle.ToUrlSegment(64),
                User = controller.User.ToUser(),
            };
            var forum = ForumsControllerTest.GetAForum();
			topic.Forum = forum;

            const int topicId = 10;
            string ip = controllerContext.RequestContext.HttpContext.Request.UserHostAddress;
            mockTopicClient.Setup(m => m.Get(topicId)).Returns(new Topic(topicId));
            mockTopicClient.Setup(m => m.Delete(topicId, topic.User.Id, ip));

            ActionResult result = controller.Delete(topicId, topic.ShortName, topic.Forum.ShortName);

            Assert.IsInstanceOf<JsonResult>(result);

            mockTopicClient.VerifyAll();
		}

/*		[Test]
		public void TagList_Test()
		{
			#region Create a valid topic and controller
			TopicsController controller = new TopicsController();
			var controllerContext = new FakeControllerContext(controller, "http://localhost", null, null, new System.Collections.Specialized.NameValueCollection(), new System.Collections.Specialized.NameValueCollection(), new System.Web.HttpCookieCollection(), ForumsControllerTest.GetSessionWithTestUser());
			controller.ControllerContext = controllerContext;
			controller.Url = new UrlHelper(controllerContext.RequestContext);

			Forum forum = ForumsControllerTest.GetAForum();

			//Create a valid topic
			Topic t = new Topic();
			t.Title = "Unit testing " + MethodInfo.GetCurrentMethod().Name;
			t.Description = "This is a sample topic from unit testing project.";
			t.Tags = new TagList("test");
            t.ShortName = t.Title.ToUrlSegment(64);
			t.User = controller.User.ToUser();
			t.Forum = forum; 
			#endregion

			TagListTestHelper(true, "hola mundo", 2, t, forum.ShortName, controller);
			TagListTestHelper(true, "hola	mundo", 2, t, forum.ShortName, controller);
			TagListTestHelper(true, "hola		mundo", 2, t, forum.ShortName, controller);
			TagListTestHelper(false, "NOTho}la", 1, t, forum.ShortName, controller);
			TagListTestHelper(true, " tag1 tag2 tag3 tag4 tag5 tag6", 6, t, forum.ShortName, controller);
			TagListTestHelper(true, "tabbedtag1 	tag2 	tag3 	tag4 	tag5 	tag6 	", 6, t, forum.ShortName, controller);
			TagListTestHelper(true, "tagdott tag2 tag3 asp.net tag", 5, t, forum.ShortName, controller);
			TagListTestHelper(false, "NOTtag tag tagtag3 tag4 tag5 tag6 tag7 tag8", 8, t, forum.ShortName, controller);
			TagListTestHelper(true, "repeated tag tag tag4 tag5 tagthisislong6", 5, t, forum.ShortName, controller);
			TagListTestHelper(true, "tag tag2 tagtag3 tag4 tag5 tagthis_islmiddlescore--ong6", 6, t, forum.ShortName, controller);
		}
 */
/*
		public void TagListTestHelper(bool valid, string tags, int tagCount, Topic t, string forumShortName, TopicsController controller)
		{
			var context = controller.ControllerContext;

			controller = new TopicsController();
			controller.ControllerContext = context;
			controller.Url = new UrlHelper(context.RequestContext);
			
			t.Id = 0;
			t.Tags = new TagList(tags);

			Assert.IsTrue(t.Tags.Count == tagCount, "Tag \"" + tags + "\" count does not match expected value");

			controller.Add(forumShortName, t, true, "admin@admin.com");
			
			int topicId = t.Id;
			if (valid)
			{
				Assert.IsTrue(topicId > 0);

				controller.Delete(topicId, t.ShortName, t.Forum.ShortName);
			}
			else
			{
				Assert.IsFalse(topicId > 0);
			}
		}
*/
/*
		[Test]
		public void EditTopic_Test()
		{
			var controller = new TopicsController();
			controller.ControllerContext = new FakeControllerContext(controller, "http://localhost", null, null, new System.Collections.Specialized.NameValueCollection(), new System.Collections.Specialized.NameValueCollection(), new System.Web.HttpCookieCollection(), ForumsControllerTest.GetSessionWithTestUser());
			ActionResult result = null;

			Forum forum = ForumsControllerTest.GetAForum();
			Topic topic = TopicsControllerTest.GetATopic(forum);


			result = controller.Edit(topic.Id, topic.ShortName, forum.ShortName, topic, true, "admin@admin.com");

			Assert.IsTrue(result is RedirectToRouteResult || result is RedirectResult);
		}
*/
/*
		[Test]
		public void Topic_OpenClose_Test()
		{
			var controller = new TopicsController();
			controller.ControllerContext = new FakeControllerContext(controller, "http://localhost", null, null, new System.Collections.Specialized.NameValueCollection(), new System.Collections.Specialized.NameValueCollection(), new System.Web.HttpCookieCollection(), ForumsControllerTest.GetSessionWithTestUser());

			Forum forum = ForumsControllerTest.GetAForum();
			Topic topic = TopicsControllerTest.GetATopic(forum);

			controller.CloseReplies(topic.Id, topic.ShortName);

			topic = TopicsServiceClient.Get(topic.Id);

			Assert.IsTrue(topic.IsClosed);

			controller.OpenReplies(topic.Id, topic.ShortName);

			topic = TopicsServiceClient.Get(topic.Id);

			Assert.IsFalse(topic.IsClosed);
		}
*/
/*
		[Test]
		public void Topic_LatestMessages_Test()
		{
			var controller = new TopicsController();
			controller.ControllerContext = new FakeControllerContext(controller, "http://localhost", null, null, new NameValueCollection(), new NameValueCollection(), new HttpCookieCollection(), ForumsControllerTest.GetSessionWithTestUser());
            controller.Url = new UrlHelper(controller.ControllerContext.RequestContext);

			Forum forum = ForumsControllerTest.GetAForum();
			Topic topic = TopicsControllerTest.GetATopic(forum);

			ActionResult result = controller.LatestMessages(topic.Id, topic.ShortName);
            Assert.IsInstanceOf<ContentResult>(result);
		}
 */
	}
}
